package com.meteor.user.service.impl;

import lombok.AllArgsConstructor;
import com.meteor.framework.security.user.UserDetail;
import com.meteor.user.mapper.SysRoleMapper;
import com.meteor.user.mapper.SysRoleDataScopeMapper;
import com.meteor.framework.common.enums.DataScopeEnum;
import com.meteor.user.enums.UserStatusEnum;
import com.meteor.user.service.SysMenuService;
import com.meteor.user.service.SysOrgService;
import com.meteor.user.service.SysUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 用户 UserDetails 信息
 *
 * @author lynn
 * @date 2024/1/03
 */
@Service
@AllArgsConstructor
public class SysUserDetailsServiceImpl implements SysUserDetailsService {
    private final SysMenuService sysMenuService;
    private final SysOrgService sysOrgService;
    private final SysRoleMapper sysRoleMapper;
    private final SysRoleDataScopeMapper sysRoleDataScopeMapper;

    @Override
    public UserDetails getUserDetails(UserDetail userDetail) {
        // 账号不可用
        if (userDetail.getStatus() == UserStatusEnum.DISABLE.getValue()) {
            userDetail.setEnabled(false);
        }

        // 数据权限范围
        List<String> dataScopeList = getDataScope(userDetail);
        userDetail.setDataScopeList(dataScopeList);

        Map<String,List<String>> dataScopeMap =  getMapDataScope(userDetail);
        userDetail.setDataScopeMap(dataScopeMap);
        // 用户权限列表
        Set<String> authoritySet = sysMenuService.getUserAuthority(userDetail);

        // 用户角色编码列表
        List<String> roleCodeList = sysRoleMapper.geRoleCodeByUserId(userDetail.getId());
        roleCodeList.forEach(roleCode -> authoritySet.add("ROLE_" + roleCode));

        userDetail.setAuthoritySet(authoritySet);

        return userDetail;
    }

    private Map<String, List<String>> getMapDataScope(UserDetail userDetail) {
        Integer dataScope = sysRoleMapper.getDataScopeByUserId(userDetail.getId());
        if (dataScope == null) {
            return new HashMap<>();
        }

        if (dataScope.equals(DataScopeEnum.ALL.getValue())) {
            // 全部数据权限，则返回null
            return null;
        } else if (dataScope.equals(DataScopeEnum.ORG_AND_CHILD.getValue())) {
            // 本机构及子机构数据
            Map<String,List<String>> dataScopeMap = sysOrgService.getSubMapOrgIdList(userDetail.getOrgId(),DataScopeEnum.ORG_AND_CHILD.getValue());
            // 自定义数据权限范围
            List<String> dataScopeList = dataScopeMap.get(DataScopeEnum.ORG_AND_CHILD.getValue().toString());
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));
            dataScopeMap = new HashMap<>();
            dataScopeMap.put(DataScopeEnum.ORG_AND_CHILD.getValue().toString(),dataScopeList);
            return dataScopeMap;
        } else if (dataScope.equals(DataScopeEnum.ORG_ONLY.getValue())) {
            // 本机构数据
            List<String> dataScopeList = new ArrayList<>();
            Map<String,List<String>> dataScopeMap = new HashMap<>();
            dataScopeList.add(userDetail.getOrgId());
            // 自定义数据权限范围
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));
            dataScopeMap.put(DataScopeEnum.ORG_ONLY.getValue().toString(),dataScopeList);

            return dataScopeMap;
        } else if (dataScope.equals(DataScopeEnum.CUSTOM.getValue())) {
            // 自定义数据权限范围
            Map<String,List<String>> dataScopeMap = new HashMap<>();
            dataScopeMap.put(DataScopeEnum.CUSTOM.getValue().toString(),sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));
            return dataScopeMap;
        }else if(dataScope.equals(DataScopeEnum.COMMUNITY.getValue())){

            // 本社区
            Map<String,List<String>> dataScopeMap = new HashMap<>();
            List<String> dataScopeList = new ArrayList<>();
            if(userDetail.getCommunityId()==null){
                return dataScopeMap;
            }
            dataScopeList.add(userDetail.getCommunityId());
            // 自定义数据权限范围
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));
            dataScopeMap.put(DataScopeEnum.COMMUNITY.getValue().toString(),dataScopeList);
            return dataScopeMap;
        }

        return new HashMap<>();
    }

    private List<String> getDataScope(UserDetail userDetail) {
        Integer dataScope = sysRoleMapper.getDataScopeByUserId(userDetail.getId());
        if (dataScope == null) {
            return new ArrayList<>();
        }

        if (dataScope.equals(DataScopeEnum.ALL.getValue())) {
            // 全部数据权限，则返回null
            return null;
        } else if (dataScope.equals(DataScopeEnum.ORG_AND_CHILD.getValue())) {
            // 本机构及子机构数据
            List<String> dataScopeList = sysOrgService.getSubOrgIdList(userDetail.getOrgId());
            // 自定义数据权限范围
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));

            return dataScopeList;
        } else if (dataScope.equals(DataScopeEnum.ORG_ONLY.getValue())) {
            // 本机构数据
            List<String> dataScopeList = new ArrayList<>();
            dataScopeList.add(userDetail.getOrgId());
            // 自定义数据权限范围
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));

            return dataScopeList;
        } else if (dataScope.equals(DataScopeEnum.CUSTOM.getValue())) {
            // 自定义数据权限范围
            return sysRoleDataScopeMapper.getDataScopeList(userDetail.getId());
        }else if(dataScope.equals(DataScopeEnum.COMMUNITY.getValue())){

            // 本社区
            List<String> dataScopeList = new ArrayList<>();
            if(userDetail.getCommunityId()==null){
                return dataScopeList;
            }
            dataScopeList.add(userDetail.getCommunityId());
            // 自定义数据权限范围
            dataScopeList.addAll(sysRoleDataScopeMapper.getDataScopeList(userDetail.getId()));

            return dataScopeList;
        }

        return new ArrayList<>();
    }
}
